#ifndef AEYE_STRUCT_TOSTR_H
#define AEYE_STRUCT_TOSTR_H

#include <ostream>
#include <cassert>

#include "AEyeSensorAPI.h"
#include "DiagnosticAPI.hpp"
#include "AEyeSDKEnumsToStr.hpp"

namespace aeye {

inline std::ostream &operator<<(std::ostream &os, const PointReturnCartesianCoords &v) {
  os << "x=" << v.x;
  os << ", y=" << v.y;
  os << ", z=" << v.z;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PointReturnSphericalCoords &v) {
  os << "azimuth=" << static_cast<float>(v.azimuth) / 10000.F;
  os << ", elevation=" << static_cast<float>(v.elevation) / 10000.F;
//  os << ", radius=" << v.radius;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PointReturnIntensity &v) {
  os << "intensity_type_data=" << v.intensity_type_data;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PointReturnUnused_8 &v) {
    os << "reserved1=" << v.reserved1;
    os << ", reserved2=" << v.reserved2;
    return os;
}
inline std::ostream &operator<<(std::ostream &os, const PointReturnUnused_2 &v) {
//  os << "frame_id=" << v.frame_id;
  os << ", reserved1=" << v.reserved1;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PointReturnUnused_6 &v) {
  os << "reserved1=" << v.reserved1;
  os << ", reserved2=" << v.reserved2;
  os << ", reserved3=" << v.reserved3;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PointReturnUnused_7 &v) {
  os << "reserved1=" << v.reserved1;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PointReturnType &v) {
  os << "point_return_mask=" << v.point_return_mask;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PointReturnUnused_1 &v) {
  os << "reserved1=" << v.reserved1;
  os << ", reserved2=" << v.reserved2;
  os << ", flags=" << v.flags;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PointReturnUnused_5 &v) {
  os << "reserved2=" << v.reserved2;
  os << ", reserved1=" << v.reserved1;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PointReturnUnused_3 &v) {
  os << "reserved1=" << v.reserved1;
  os << ", reserved2=" << v.reserved2;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const AEyePoint &v) {
  os << "pointReturnCartesianCoords=" << v.pointReturnCartesianCoords;
  os << ", pointReturnSphericalCoords=" << v.pointReturnSphericalCoords;
  os << ", pointReturnUnused_2=" << v.pointReturnUnused_2;
  os << ", pointReturnIntensity=" << v.pointReturnIntensity;
  os << ", pointReturnUnused_8=" << v.pointReturnUnused_8;
  os << ", pointReturnUnused_6=" << v.pointReturnUnused_6;
  os << ", pointReturnType=" << v.pointReturnType;
  os << ", pointReturnUnused_7=" << v.pointReturnUnused_7;
  os << ", pointReturnUnused_1=" << v.pointReturnUnused_1;
  os << ", pointReturnUnused_5=" << v.pointReturnUnused_5;
  os << ", pointReturnUnused_3=" << v.pointReturnUnused_3;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const Quadrilateral &v) {
  os << "topLeftX=" << v.topLeftX;
  os << ", topLeftY=" << v.topLeftY;
  os << ", topRightX=" << v.topRightX;
  os << ", topRightY=" << v.topRightY;
  os << ", btmLeftX=" << v.btmLeftX;
  os << ", btmLeftY=" << v.btmLeftY;
  os << ", btmRightX=" << v.btmRightX;
  os << ", btmRightY=" << v.btmRightY;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const IrpsGlobalStatus &v) {
  os << "syncState=" << v.syncState;
  os << ", syncInRange=" << v.syncInRange;
  os << ", vccUvFault=" << v.vccUvFault;
  os << ", vdrvUvFault=" << v.vdrvUvFault;
  os << ", roAlertSignals=" << v.roAlertSignals;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const IrpsGlobalPacket &v) {
  os << "irpsGlobStat=" << v.irpsGlobStat;
  os << ", globVcc=" << v.globVcc;
  os << ", globVdrv=" << v.globVdrv;
  os << ", globTotalInputPwr=" << v.globTotalInputPwr;
  os << ", pktCt=" << v.pktCt;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const IrpsChannelStatus1 &v) {
  os << "channelState=" << v.channelState;
  os << ", statusCml=" << v.statusCml;
  os << ", statusWord=" << v.statusWord;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const IrpsChannelStatus2 &v) {
  os << "statusTemp=" << v.statusTemp;
  os << ", statusInput=" << v.statusInput;
  os << ", statusIout=" << v.statusIout;
  os << ", statusVout=" << v.statusVout;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const IrpsPerChannelPacket &v) {
  os << "irpsChannelStatus1=" << v.irpsChannelStatus1;
  os << ", irpsChannelStatus2=" << v.irpsChannelStatus2;
  os << ", chVin=" << v.chVin;
  os << ", chIin=" << v.chIin;
  os << ", chPin=" << v.chPin;
  os << ", chVout=" << v.chVout;
  os << ", chIout=" << v.chIout;
  os << ", chPout=" << v.chPout;
  os << ", chTemp=" << v.chTemp;
  os << ", chVoutPeak=" << v.chVoutPeak;
  os << ", chIoutPeak=" << v.chIoutPeak;
  os << ", chTempPeak=" << v.chTempPeak;
  os << ", pktCt=" << v.pktCt;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const IrpsDevPacket &v) {
  os << "irpsGlobPkt=" << v.irpsGlobPkt;
  os << ", irpsPerChPkt0=" << v.irpsPerChPkt0;
  os << ", irpsPerChPkt1=" << v.irpsPerChPkt1;
  os << ", irpsPerChPkt2=" << v.irpsPerChPkt2;
  os << ", irpsPerChPkt3=" << v.irpsPerChPkt3;
  os << ", irpsPerChPkt4=" << v.irpsPerChPkt4;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketDiagnosticBody &v) {
  os << "sensorId=" << v.sensorId;
  os << ", telemRev=" << v.telemRev;
  os << ", brdTempCels=" << v.brdTempCels;
  os << ", lsrTempCels=" << v.lsrTempCels;
  os << ", scanheadTempCels=" << v.scanheadTempCels;
  os << ", scanheadRh=" << v.scanheadRh;
  os << ", scanWindowTempCels=" << v.scanWindowTempCels;
  os << ", scanWindowRh=" << v.scanWindowRh;
  os << ", brdTempNearAdcCels=" << v.brdTempNearAdcCels;
  os << ", adcTempCels=" << v.adcTempCels;
  os << ", irpsDev0Packet=" << v.irpsDev0Packet;
  os << ", irpsDev1Packet=" << v.irpsDev1Packet;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const DiagnosticData &v) {
  os << "sensorId=" << v.sensorId;
  os << ", telemRev=" << v.telemRev;
  os << ", brdTempCels=" << v.brdTempCels;
  os << ", lsrTempCels=" << v.lsrTempCels;
  os << ", scanheadTempCels=" << v.scanheadTempCels;
  os << ", scanheadRh=" << v.scanheadRh;
  os << ", scanWindowTempCels=" << v.scanWindowTempCels;
  os << ", scanWindowRh=" << v.scanWindowRh;
  os << ", brdTempNearAdcCels=" << v.brdTempNearAdcCels;
  os << ", adcTempCels=" << v.adcTempCels;
  os << ", irpsDev0Packet=" << v.irpsDev0Packet;
  os << ", irpsDev1Packet=" << v.irpsDev1Packet;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketHeader &v) {
  os << "marker=" << v.marker;
  os << ", type=" << v.type;
  os << ", version=" << v.version;
  os << ", bodySize=" << v.bodySize;
  os << ", flags=" << v.flags;
  os << ", tsSec=" << v.tsSec;
  os << ", tsuSec=" << v.tsuSec;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketGenericBody &v) {
  os << "bodySize=" << v.bodySize;
  os << ", &body=" << &v.body;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketReturnDefault &v) {
  os << "type=" << v.type;
  os << ", version=" << v.version;
  os << ", status=" << v.status;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketBuildInfoBody &v) {
  os << "status=" << v.status;
  os << ", rxType=" << v.rxType;
  os << ", rxMajorRevision=" << v.rxMajorRevision;
  os << ", rxBuildTimestamp=" << v.rxBuildTimestamp;
  os << ", buildInfo=" << v.buildInfo;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketHWModelInfoBody &v) {
  os << "hwModel=" << v.hwModel;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketSetActiveZoneBody &v) {
  os << "activeZone=" << v.activeZone;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketLaserPositionRegionBody &v) {
  os << "regionOfInterest=" << v.regionOfInterest;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketLaserFOVBody &v) {
  os << "laserHFovDegree=" << v.laserHFovDegree;
  os << ", laserVFovDegree=" << v.laserVFovDegree;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketRangeZeroPointCal &v) {
  os << "rngZeroPointCal=" << v.rngZeroPointCal;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketSetPassiveModeBody &v) {
  os << "mode=" << v.mode;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketSetPassiveParamBody &v) {
  os << "param=" << v.param;
  os << ", value=" << v.value;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketSetPoseBody &v) {
  os << "x=" << v.x;
  os << ", y=" << v.y;
  os << ", z=" << v.z;
  os << ", yaw=" << v.yaw;
  os << ", pitch=" << v.pitch;
  os << ", roll=" << v.roll;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketSetLongBufferForAllBody &v) {
  os << "useFullADCBufferForAll=" << v.useFullADCBufferForAll;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketEnergyZonesBody &v) {
  os << "energyZonesEnabled=" << v.energyZonesEnabled;
  os << ", topDivider=" << v.topDivider;
  os << ", bottomDivider=" << v.bottomDivider;
  os << ", topEnergy=" << v.topEnergy;
  os << ", middleEnergy=" << v.middleEnergy;
  os << ", bottomEnergy=" << v.bottomEnergy;
  os << ", roiEnergy=" << v.roiEnergy;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketGetPoseBody &v) {
  os << "status=" << v.status;
  os << ", x=" << v.x;
  os << ", y=" << v.y;
  os << ", z=" << v.z;
  os << ", yaw=" << v.yaw;
  os << ", pitch=" << v.pitch;
  os << ", roll=" << v.roll;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketGetPassiveSensingStateBody &v) {
  os << "status=" << v.status;
  os << ", xLowerBound=" << v.xLowerBound;
  os << ", yLowerBound=" << v.yLowerBound;
  os << ", xUpperBound=" << v.xUpperBound;
  os << ", yUpperBound=" << v.yUpperBound;
  os << ", gridRowNum=" << v.gridRowNum;
  os << ", gridColNum=" << v.gridColNum;
  os << ", randomRowNum=" << v.randomRowNum;
  os << ", randomColNum=" << v.randomColNum;
  os << ", offsetGridRowNum=" << v.offsetGridRowNum;
  os << ", offsetGridColNum=" << v.offsetGridColNum;
  os << ", gridColumnOffset=" << v.gridColumnOffset;
  os << ", movingGridRowNum=" << v.movingGridRowNum;
  os << ", movingGridColNum=" << v.movingGridColNum;
  os << ", gridRowSpeed=" << v.gridRowSpeed;
  os << ", gridColSpeed=" << v.gridColSpeed;
  os << ", foveatedGridRowNum=" << v.foveatedGridRowNum;
  os << ", foveatedGridColNum=" << v.foveatedGridColNum;
  os << ", gridFoveationCoefficientRow=" << v.gridFoveationCoefficientRow;
  os << ", gridFoveationCoefficientCol=" << v.gridFoveationCoefficientCol;
  os << ", foveatedGridCenterRow=" << v.foveatedGridCenterRow;
  os << ", foveatedGridCenterCol=" << v.foveatedGridCenterCol;
  os << ", foveatedRandomRowNum=" << v.foveatedRandomRowNum;
  os << ", foveatedRandomColNum=" << v.foveatedRandomColNum;
  os << ", randomFoveationCoefficientRow=" << v.randomFoveationCoefficientRow;
  os << ", randomFoveationCoefficientCol=" << v.randomFoveationCoefficientCol;
  os << ", foveatedRandomCenterRow=" << v.foveatedRandomCenterRow;
  os << ", foveatedRandomCenterCol=" << v.foveatedRandomCenterCol;
  os << ", shotlistIdx=" << v.shotlistIdx;
  os << ", passiveSensingMode=" << v.passiveSensingMode;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketGetERPsStateBody &v) {
  os << "status=" << v.status;
  os << ", ERPsEnabled=" << v.ERPsEnabled;
  os << ", ERPsNumShots=" << v.ERPsNumShots;
  os << ", ERPsHorLaserIncr=" << v.ERPsHorLaserIncr;
  os << ", ERPsVertLaserIncr=" << v.ERPsVertLaserIncr;
  os << ", ERPsBoxTopLeftX=" << v.ERPsBoxTopLeftX;
  os << ", ERPsBoxTopLeftY=" << v.ERPsBoxTopLeftY;
  os << ", ERPsBoxWidth=" << v.ERPsBoxWidth;
  os << ", ERPsBoxHeight=" << v.ERPsBoxHeight;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketGetLaserStateBodyReturnV2 &v) {
  os << "status=" << v.status;
  os << ", laserPower=" << v.laserPower;
  os << ", laserHFovDegree=" << v.laserHFovDegree;
  os << ", laserVFovDegree=" << v.laserVFovDegree;
  os << ", laserZone=" << v.laserZone;
  os << ", scannerHRes=" << v.scannerHRes;
  os << ", scannerVRes=" << v.scannerVRes;
  return os;
}

inline std::ostream &operator<<(std::ostream &os, const PacketSetPointReturnMask &v) {
  os << "pointReturnMask=" << v.pointReturnMask;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketSetIntensityType &v) {
os << "value=" << v.value;
return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketSetRangeGateDelayBody &v) {
  os << "rangeGateDelay=" << v.rangeGateDelay;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketStartBody &v) {
  os << "clientIp=" << v.clientIp;
  os << ", rangePort=" << v.rangePort;
  os << ", cameraPort=" << v.cameraPort;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketSendMarkerPoints &v) {
  os << "sendMarkerPoints=" << v.sendMarkerPoints;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PointReturnsBody &v) {
  os << "sensorId=" << v.sensorId;
  os << ", frameId=" << v.frameId;
  os << ", seqNum=" << v.seqNum;
  os << ", seqTotal=" << v.seqTotal;
  os << ", pointReturnMask=" << v.pointReturnMask;
  os << ", &pointData=" << &v.pointData;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketPointsReturn &v) {
  os << "header=" << v.header;
  os << ", body=" << v.body;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketPointCloudDelimiter &v) {
  os << "header=" << v.header;
  os << ", frameId=" << v.frameId;
  os << ", numPointsTotalInFrame=" << v.numPointsTotalInFrame;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketNetworkConfigBody &v) {
  os << "serverIp=" << v.serverIp;
  os << ", netmask=" << v.netmask;
  os << ", gateway=" << v.gateway;
  os << ", commandPort=" << v.commandPort;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketSetNtpBody &v) {
  os << "useNTP=" << v.useNTP;
  os << ", serverIp=" << v.serverIp;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketSetPtpBody &v) {
  os << "usePTP=" << v.usePTP;
  os << ", serverIp=" << v.serverIp;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketSetGptpBody &v) {
  os << "useGPTP=" << v.useGPTP;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketGetNtpStatus &v) {
  os << "status=" << v.status;
  os << ", NTPstatus=" << v.NTPstatus;
  os << ", timeCorrectness=" << v.timeCorrectness;
  os << ", timeConstant=" << v.timeConstant;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketGetPtpStatus &v) {
  os << "status=" << v.status;
  os << ", PTPstatus=" << v.PTPstatus;
  os << ", timeStamp=" << v.timeStamp;
  os << ", state=" << v.state;
  os << ", clockId=" << v.clockId;
  os << ", oneWayDelay=" << v.oneWayDelay;
  os << ", offsetFromMaster=" << v.offsetFromMaster;
  os << ", slaveToMaster=" << v.slaveToMaster;
  os << ", masterToSlave=" << v.masterToSlave;
  os << ", observedDrift=" << v.observedDrift;
  os << ", lastPacketReceived=" << v.lastPacketReceived;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketGetGptpStatus &v) {
  os << "status=" << v.status;
  os << ", gPTPstatus=" << v.gPTPstatus;
  os << ", stepsRemoved=" << v.stepsRemoved;
  os << ", offsetFromMaster=" << v.offsetFromMaster;
  os << ", meanPathDelay=" << v.meanPathDelay;
  os << ", masterOffset=" << v.masterOffset;
  os << ", ingressTime=" << v.ingress_time;
  os << ", cumulativeScaledRateOffset=" << v.cumulativeScaledRateOffset;
  os << ", scaledLastGmPhaserChange=" << v.scaledLastGmPhaserChange;
  os << ", gmPresent=" << v.gmPresent;
  os << ", gmIdentity=" << v.gmIdentity;
  os << ", portIdentity=" << v.portIdentity;
  os << ", portState=" << v.portState;
  os << ", logMinDelayReqInterval=" << v.logMinDelayReqInterval;
  os << ", peerMeanPathDelay=" << v.peerMeanPathDelay;
  os << ", logAnnounceInterval=" << v.logAnnounceInterval;
  os << ", announceReceiptTimeout=" << v.announceReceiptTimeout;
  os << ", logSyncInterval=" << v.logSyncInterval;
  os << ", delayMechanism=" << v.delayMechanism;
  os << ", logMindPdelayReqInterval=" << v.logMinDelayReqInterval;
  os << ", versionNumber=" << v.versionNumber;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketTimeBody &v) {
  os << "tvSec=" << v.tvSec;
  os << ", tvuSec=" << v.tvuSec;
  os << ", tzMinutesWest=" << v.tzMinutesWest;
  os << ", tzDstTime=" << v.tzDstTime;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketSetNumMultiEchoes &v) {
  os << "numEchoes=" << v.numEchoes;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketSetModeMultiEchoes &v) {
  os << "modeMultiEchoes=" << v.modeMultiEchoes;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketGetNumMultiEchoes &v) {
  os << "status=" << v.status;
  os << ", numEchoes=" << v.numEchoes;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketGetModeMultiEchoes &v) {
  os << "status=" << v.status;
  os << ", mode=" << v.mode;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketSetSkirtThreshValue &v) {
  os << "value=" << v.value;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketGetSkirtThreshValue &v) {
  os << "status=" << v.status;
  os << ", value=" << v.value;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketGetShotlistNameBody &v) {
  os << "shotlistIdx=" << v.shotlistIdx;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketReturnShotlistNameBody &v) {
  os << "status=" << v.status;
  os << ", stringLength=" << v.stringLength;
  os << ", shotlistName=" << v.shotlistName;
  return os;
}
inline std::ostream &operator<<(std::ostream &os, const PacketDiagnosticData &v) {
  os << "header=" << v.header;
  os << ", body=" << v.body;
  return os;
}

std::string ToStr(AEyeCommands v);
std::ostream &operator<<(std::ostream &os, AEyeCommands v);

}

#endif